/*
 * Copyright © 2018 www.noark.xyz All Rights Reserved.
 * 
 * 感谢您选择Noark框架，希望我们的努力能为您提供一个简单、易用、稳定的服务器端框架 ！
 * 除非符合Noark许可协议，否则不得使用该文件，您可以下载许可协议文件：
 * 
 * 		http://www.noark.xyz/LICENSE
 *
 * 1.未经许可，任何公司及个人不得以任何方式或理由对本框架进行修改、使用和传播;
 * 2.禁止在本项目或任何子项目的基础上发展任何派生版本、修改版本或第三方版本;
 * 3.无论你对源代码做出任何修改和改进，版权都归Noark研发团队所有，我们保留所有权利;
 * 4.凡侵犯Noark版权等知识产权的，必依法追究其法律责任，特此郑重法律声明！
 */
package com.company.majiang.core;

import java.io.IOException;

import com.company.majiang.isnowfox.Input;
import com.company.majiang.isnowfox.MarkCompressInput;
import com.company.majiang.isnowfox.MarkCompressOutput;
import com.company.majiang.isnowfox.Message;
import com.company.majiang.isnowfox.Output;
import com.company.majiang.isnowfox.ProtocolException;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import xyz.noark.core.lang.ByteArray;
import xyz.noark.core.lang.ImmutableByteArray;
import xyz.noark.core.network.NetworkPacket;
import xyz.noark.core.network.NetworkProtocol;
import xyz.noark.core.util.ByteBufUtils;
import xyz.noark.core.util.ClassUtils;
import xyz.noark.network.codec.AbstractWebsocketPacketCodec;
import xyz.noark.network.codec.DefaultNetworkPacket;

/**
 * 封包解码器.
 *
 * @author 小流氓(176543888@qq.com)
 */
public class MjPacketCodec extends AbstractWebsocketPacketCodec {

	@Override
	public NetworkPacket decodePacket(ByteBuf byteBuf) {
		DefaultNetworkPacket packet = new DefaultNetworkPacket();
		// 封包长度，虽然没有什么用
		packet.setLength(byteBuf.readableBytes());

		try {// 原来协议有两个一个类型，一个ID，这里就用一种简单的方法合起来了
			Input i = MarkCompressInput.create(byteBuf);
			int type = i.readInt();
			int id = i.readInt();
			packet.setOpcode(type * 100 + id);
		} catch (IOException | ProtocolException e) {
			e.printStackTrace();
		}

		// 包体
		packet.setBytes(new ByteBufHolder(byteBuf));
		return packet;
	}

	@Override
	public <T> T decodeProtocol(ByteArray bytes, Class<T> klass) {
		T message = ClassUtils.newInstance(klass);
		ByteBufHolder wrapper = (ByteBufHolder) bytes;
		try {
			((Message) message).decode(MarkCompressInput.create(wrapper.getByteBuf()));
		} catch (IOException | ProtocolException e) {
			e.printStackTrace();
		}
		return message;
	}

	@Override
	public ByteArray encodePacket(NetworkProtocol protocol) {
		Message msg = (Message) protocol.getProtocol();
		ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
		Output o = MarkCompressOutput.create(buf);
		try {
			int op = protocol.getOpcode();
			o.writeInt(op / 100);
			o.writeInt(op % 100);
			msg.encode(o);
		} catch (IOException | ProtocolException e) {
			e.printStackTrace();
		}
		return new ImmutableByteArray(ByteBufUtils.readBytes(o.getByteBuf()));
	}
}